home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 05 - 1989 / 05.01 Jan 89 / Bezier Application / Bezier.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-11  |  2.4 KB  |  121 lines  |  [TEXT/KAHL]

  1. /*
  2. **  Bezier  --  Support for Bezier curves
  3. **
  4. **        Herein reside support routines for drawing Bezier curves.
  5. **
  6. **  Copyright (C) 1987, 1988 David W. Smith
  7. **  Submitted to MacTutor for their source-disk.
  8. */
  9.  
  10. #include <MacTypes.h>
  11.  
  12.  
  13. /*
  14.  *  The greater the number of curve segments, the smoother the curve,
  15.  *  and the longer it takes to generate and draw.  The number below was
  16.  *  pulled out of a hat, and seems to work o.k.
  17.  */
  18. #define SEGMENTS    16
  19.  
  20. static Fixed    weight1[SEGMENTS + 1];
  21. static Fixed    weight2[SEGMENTS + 1];
  22.  
  23. #define    w1(s)    weight1[s]
  24. #define w2(s)    weight2[s]
  25. #define    w3(s)    weight2[SEGMENTS - s]
  26. #define w4(s)    weight1[SEGMENTS - s]
  27.  
  28.  
  29.  
  30. /*
  31.  *  SetupBezier  --  one-time setup code.
  32.  *
  33.  *        Compute the weights for the Bezier function.
  34.  *
  35.  *  For the those concerned with space, the tables can be precomputed.
  36.  *  The setup is done here for purposes of illustration.
  37.  */
  38. void
  39. SetupBezier()
  40. {
  41.     Fixed                t, zero, one;
  42.     int                    s;
  43.  
  44.     zero  = FixRatio(0, 1);
  45.     one   = FixRatio(1, 1);
  46.  
  47.     weight1[0] = one;
  48.     weight2[0] = zero;
  49.  
  50.     for ( s = 1 ; s < SEGMENTS ; ++s )
  51.     {
  52.         t = FixRatio(s, SEGMENTS);
  53.  
  54.         weight1[s] = FixMul(one - t, FixMul(one - t, one - t));
  55.         weight2[s] = 3 * FixMul(t, FixMul(t - one, t - one));
  56.     }
  57.  
  58.     weight1[SEGMENTS] = zero;
  59.     weight2[SEGMENTS] = zero;
  60. }
  61.  
  62.  
  63. /*
  64.  *  computeSegments  --  compute segments for the Bezier curve
  65.  *
  66.  *        Compute the segments along the curve.
  67.  *
  68.  *  The curve touches the endpoints, so don't bother to compute them.
  69.  */
  70. static void
  71. computeSegments(p1, p2, p3, p4, segment)
  72.     Point                p1, p2, p3, p4;
  73.     Point                segment[];
  74. {
  75.     int                    s;
  76.     
  77.     segment[0] = p1;
  78.  
  79.     for ( s = 1 ; s < SEGMENTS ; ++s )
  80.     {
  81.         segment[s].v = FixRound(w1(s) * p1.v + w2(s) * p2.v +
  82.                                 w3(s) * p3.v + w4(s) * p4.v);
  83.  
  84.         segment[s].h = FixRound(w1(s) * p1.h + w2(s) * p2.h +
  85.                                 w3(s) * p3.h + w4(s) * p4.h);
  86.     }
  87.  
  88.     segment[SEGMENTS] = p4;
  89. }
  90.  
  91.  
  92. /*
  93.  *  BezierCurve  --  Draw a Bezier Curve
  94.  *
  95.  *        Draw a curve with the given endpoints (p1, p4), and the given 
  96.  *        control points (p2, p3).
  97.  *
  98.  *  Note that we make no assumptions about the pen or pen mode.
  99.  */
  100. void
  101. BezierCurve(p1, p2, p3, p4)
  102.     Point                p1, p2, p3, p4;
  103. {
  104.     int                    s;
  105.     Point                segment[SEGMENTS + 1];
  106.  
  107.     computeSegments(p1, p2, p3, p4, segment);
  108.  
  109.     MoveTo(segment[0].h, segment[0].v);
  110.  
  111.     for ( s = 1 ; s <= SEGMENTS ; ++s )
  112.     {
  113.         if ( segment[s].h != segment[s - 1].h ||
  114.              segment[s].v != segment[s - 1].v )
  115.         {
  116.             LineTo(segment[s].h, segment[s].v);
  117.         }
  118.     }
  119. }
  120.  
  121.